﻿using Cofe.Core.Filter;
using Cofe.Core.Interfaces;
using Cofe.Core.Property;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cofe.Core.Property
{
    public static class IPropertyHostActionExtension
    {
        //public static bool CanList(this IPropertyHost propertyHost)
        //{
        //    return propertyHost.IsPropertySupported(CofeDirectoryProperties.ListAsync) ||
        //        propertyHost.IsPropertySupported(CofeDirectoryProperties.List);
        //}


        //private static ParameterDic createParameterDic(IEntryFilter[] entryFilters, IOptionFilter[] optionFilters)
        //{
        //    return new ParameterDic() { { "EntryFilters", entryFilters }, { "OptionFilters", optionFilters } }; 
        //}

        //public static async Task<IEnumerable<ICofeSystemInfo>> ListAsync(this IPropertyHost propertyHost,
        //    IEntryFilter[] entryFilters, IOptionFilter[] optionFilters, IEntryConstructor entryConstructor = null)
        //{
        //    if (propertyHost.CanList())
        //    {
        //        ParameterDic pm = createParameterDic(entryFilters, optionFilters);
        //        var retPPs = await propertyHost.InvokeAsync<IEnumerable<IPropertyProvider>>(CofeDirectoryProperties.ListAsync, pm);
        //        var retPHs = retPPs.Select((pp) => entryConstructor.ConstructPropertyHost(pp));
        //        var entryTasks = retPHs.Select(async (ph) => await entryConstructor.ConstructEntryAsync(ph));

        //        Task.WaitAll(entryTasks.ToArray());

        //        return from t in entryTasks select t.Result;
        //    }
        //    else throw new NotSupportedException("List is not supported.");            
        //}

        //public static IEnumerable<ICofeSystemInfo> List(this IPropertyHost propertyHost,
        //    IEntryFilter[] entryFilters, IOptionFilter[] optionFilters, IEntryConstructor entryConstructor)
        //{
        //    if (propertyHost.CanList())
        //    {
        //        ParameterDic pm = createParameterDic(entryFilters, optionFilters);
        //        var ppEtor = propertyHost.Invoke<IEnumerable<IPropertyProvider>>(CofeDirectoryProperties.List, pm).GetEnumerator();
        //        while (ppEtor.MoveNext())
        //        {
        //            var task = entryConstructor.ConstructEntryAsync(entryConstructor.ConstructPropertyHost(ppEtor.Current));
        //            yield return task.Result;
        //        }
        //    }
        //    else throw new NotSupportedException("List is not supported.");
        //}

        public static async Task<ICofeSystemInfo> CreateAsync(this IPropertyHost propertyHost, ParameterDic pm, 
            IEntryConstructor entryConstructor)
        {
            if (propertyHost.Behaviors.CanCreate())
            {
                var retPP = await propertyHost.Behaviors.InvokeAsync<IPropertyProvider>(CofeDirectoryProperties.CreateAsync, pm);
                if (retPP == null)
                    throw new Exception("Error when creating new entries.");
                var retPH = entryConstructor.ConstructPropertyHost(retPP);
                var retVal = await entryConstructor.ConstructEntryAsync(retPH);
                return retVal;
            }
            throw new NotSupportedException("Create is not supported.");
        }

        public static async Task DeleteAsync(this IPropertyHost propertyHost, ParameterDic pm)
        {
            if (propertyHost.Behaviors.CanDelete())
                await propertyHost.Behaviors.InvokeAsync(CofeProperties.DeleteAsync, pm);            
            else throw new NotSupportedException("Delete is not supported.");
        }

      
    }
}
